/**
 * Created by chengxm on 2018-04-09.
 */
import { Component, NgZone, OnInit, Renderer2, ViewEncapsulation } from '@angular/core';
import { GridConfigService } from '@core/config/grid-config.service';
import { ApesRenderSelectComponent } from '@shared/ag-grid-ext/cell-renders/render-select.component';

import {
  deepCompare,
  exists,
  extend,
  getO,
  getValueUsingField,
  missing,
  type,
  getText,
  missingOrEmpty,
  replaceAll,
  deepClone,
  agCurrency, agNumber, getJson,
} from '../../../../utils/utils';

import { Events } from '@core/services/events/Events';
import { ExpressionService } from '@core/services/expression/ExpressionService';
import { ApiService } from '@core/services/http/api.service';
import { ApesField } from '@shared/ui-zorro/src/types/apes-field';
import { EditorCombogridComponent } from '@shared/ag-grid-ext/cell-editors/editor-combogrid.component';
import { SubjectService } from '@core/services/events/subject.service';
import { EditorInputNumberComponent } from '@shared/ag-grid-ext/cell-editors/editor-input-number.component';
import { EditorDateComponent } from '@shared/ag-grid-ext/cell-editors/editor-date.component';
import { EditorUomSelectComponent } from '@shared/ag-grid-ext/cell-editors/editor-uom-select.component';
import { EditorSelectComponent } from '@shared/ag-grid-ext/cell-editors/editor-select.component';
import { EditorInputComponent } from '@shared/ag-grid-ext/cell-editors/editor-input.component';
import { XlsxService } from '@shared/apes/xlsx';
import { toBoolean, toNumber } from '@shared/apes/core/util/convert';
import { EditorTextAreaComponent } from '@shared/ag-grid-ext/cell-editors/editor-textarea.component';
import { RenderDialogComponent } from '@shared/ag-grid-ext/cell-renders/render-dialog.component';
import { EditorChartSelectComponent } from '@shared/ag-grid-ext/cell-editors/editor-chart-select.component';
import { ApesModalRef, ApesModalService } from '@shared/apes/modal';
import { EditorCheckBoxComponent } from '@shared/ag-grid-ext/cell-editors/edit-checkbox.component';
import { EditorTimeRangeComponent } from '@shared/ag-grid-ext/cell-editors/editor-time-range.component';
import { ApesRenderTimeRangeComponent } from '@shared/ag-grid-ext/cell-renders/render-time-range.component';
import { RenderImageReviewComponent } from '@shared/ag-grid-ext/cell-renders/render-image-review.component';
import { UploadFile } from '@shared/apes/upload';
import { RenderSwitchComponent } from '@shared/ag-grid-ext/cell-renders/render-switch.component';
import { EditorDetailsComponent } from '@shared/ag-grid-ext/cell-editors/editor-details.component';
import { RenderOperatingButtonComponent } from '@shared/ag-grid-ext/cell-renders/render-operating-button.component';
import { SearchService } from '@core/services/search.service';
import { RenderSortComponent } from '@shared/ag-grid-ext/cell-renders/render-sort.component';
import { ApesInputFormComponent } from '@shared/apes-input-form/apes-input-form.component';
import { EditorTimeComponent } from '@shared/ag-grid-ext/cell-editors/editor-time.component';
import { ApesMessageService } from '@shared/apes/message';
import { ApesRenderTimeComponent } from '@shared/ag-grid-ext/cell-renders/render-time.component';
import { RenderUploadComponent } from '@shared/ag-grid-ext/cell-renders/render-upload.component';
import { debounceTime, map } from 'rxjs/operators';
import { CustomTooltip } from '@shared/ag-grid-ext/cell-renders/custom-tooltip.component';
import { EditorCityPickerComponent } from '@shared/ag-grid-ext/cell-editors/editor-city-picker.component';
import { ApesRenderCityPicker } from '@shared/ag-grid-ext/cell-renders/render-city-picker.component';
import { AreaService } from '@core/services/masterdata/area.service';
import { ApesRenderDefaultComponent } from '@shared/ag-grid-ext/cell-renders/render-default.component';
import { EditorTagSelectComponent } from '@shared/ag-grid-ext/cell-editors/editor-tag-select.component';
import { ApesRenderPopoverComponent } from '@shared/ag-grid-ext/cell-renders/render-popover.component';
import { ApesRenderBadgeComponent } from '@shared/ag-grid-ext/cell-renders/render-badge.component';
import { AllModules, Module } from '@ag-grid-enterprise/all-modules';
import { format } from 'date-fns';
import { Router } from '@angular/router';
import { FormService } from '@core/services/form.service';
import { DialogInquiryComponent } from '@shared/dialog-inquiry';
import { DialogPriceAdvanceComponent } from '@shared/dialog-price-advance';
import { RenderTooltipComponent } from '@shared/ag-grid-ext/cell-renders/render-tooltip.component';
import { CustomHeaderComponent } from '@shared/ag-grid-ext/header-component/custom-header.component';
import { ShowHiddenHeaderComponent } from '@shared/ag-grid-ext/header-component/showHidden-header.component';
import { RenderShowHiddenComponent } from '@shared/ag-grid-ext/cell-renders/render-showHidden.component';
import { RenderDetailComponent } from '@shared/ag-grid-ext/cell-renders/render-detail.component';
import { RenderCustomDetailComponent } from '@shared/ag-grid-ext/cell-renders/render-custom-detail.component';
import { RenderTagComponent } from '@shared/ag-grid-ext/cell-renders/render-tag.component';
import { ButtonHeaderComponent } from '@shared/ag-grid-ext/header-component/button-header.component';
import { Subject } from 'rxjs/internal/Subject';
import { ButtonFilterComponent } from '@shared/ag-grid-ext/filter-component/button-filter.component';
import { FormlyFieldConfig, FormlyFormOptions } from '@ngx-formly/core';
import { FormGroup } from '@angular/forms';
import { EditorInputGroupComponent } from '@shared/ag-grid-ext/cell-editors/editor-input-group.component';
import { EditorDateMonthComponent } from '@shared/ag-grid-ext/cell-editors/editor-dateMonth.component';
import { DialogMakeInquiryComponent } from '@shared/dialog-make-inquiry';
import { RenderXmlDetailComponent } from '@shared/ag-grid-ext/cell-renders/render-xml-detail.component';

function operationCellRenderer(params) {
  if (params.node.hovered) {
    return `<div class="ag-editor-button">
                  <i class="plus" id="add"></i>
                  <i class="delete" id="del"></i>
               </div>`;
  }
  return params.rowIndex + 1;
}

// <!--<input type="file" (change)="change($event)" multiple="false" class="ml-sm" [disabled]="to.disabled" /> -->
@Component({
  selector: 'formly-field-grid',
  template: `
    <!--    style="display:inline-flex;"-->
    <div *ngIf="!getHide()" (mouseover)="onBtStopEditing()">
      <div *ngIf="!getButtonHide('add')" style="display:inline-flex;">
        <button class="grid-button" type="button" apes-button (click)="onInsertRow()"
                [disabled]="to.disabled || valid == false">
          添加
        </button>
      </div>
      <div *ngIf="!getButtonHide('delete')" style="display:inline-flex;">
        <button class="grid-button" type="button" apes-button
                (click)="onRemoveSelected()"
                [disabled]="to.disabled || getAllRowDataCount() == 0 ">
          删除
        </button>
      </div>
      <div *ngIf="getButtonList()" style="display:inline-flex;">
        <ng-container *ngFor="let btn of buttonList; let i = index;">
          <button class="grid-button" *ngIf="!getButtonHide(btn.id)" type="button" apes-button
                  (click)="onDynamicClick(btn,i)"
                  [disabled]="to.disabled"
                  [id]="btn.stepGuide">
            {{btn.name}}
          </button>
        </ng-container>
      </div>
      <div *ngIf="getImport()" style="display:inline-flex;">
        <button class="grid-button" *ngIf="!getButtonHide('export')" type="button" apes-button (click)="onBtExport()">导出
          <!--[disabled]="to.disabled || getAllRowDataCount() == 0 ">导出-->
        </button>
        <button class="grid-button" *ngIf="!getButtonHide('import')" type="button" apes-button (click)="onBtImport()"
                [apesLoading]="btnImportLoading"
                [disabled]="to.disabled">导入
        </button>

        <!--        <apes-modal [(apesVisible)]="importVisible" apesTitle="The first Modal" (apesOnCancel)="handleCancel()" (apesOnOk)="handleOk()">-->
        <!--          <p>Content one</p>-->
        <!--          <p>Content two</p>-->
        <!--          <p>Content three</p>-->
        <!--        </apes-modal>-->


        <!--<input type="file" (change)="change($event)" multiple="false" class="ml-sm grid-upload" [disabled]="to.disabled" />-->
        <apes-upload *ngIf="!getButtonHide('upload')" class="apes-gird-upload" [(apesFileList)]="fileList"
                     [apesBeforeUpload]="beforeUpload"
                     [apesLimit]="'1'">
          <button class="grid-button" apes-button [disabled]="to.disabled" type="button">
            <i apes-icon apesType="upload"></i><span>选择文件</span>
          </button>
        </apes-upload>
      </div>
      <div *ngIf="filtrationSearch" style="display:inline-flex; padding: 0 5px 5px;">
        <div>
          <apes-input-group [apesPrefix]="prefixIconSearch" [apesSuffix]="suffixIconClear">
            <input apes-input type="search"
                   style="width:100%"
                   [(ngModel)]="quickSearchInput"
                   id="filter-text-box"
                   [placeholder]="filtrationText"
                   (input)="onFilterTextBoxChanged()"
                   (keyup)="onFilterTextBoxChanged()"
                   (click)="onFilterTextBoxChanged()"
                   class="search-input">
          </apes-input-group>
          <ng-template #prefixIconSearch>
            <img [src]="'./assets/tmp/img/fn/search.png'"/>
          </ng-template>
          <ng-template #suffixIconClear>
            <i apes-icon apesType="close-circle" *ngIf="quickSearchInput != null && quickSearchInput != ''"
               (click)="clearSearch()"></i>
          </ng-template>
        </div>
      </div>
      <div *ngIf="btnRemarks != ''" style="color: red;padding: 3px 10px;">{{btnRemarks}}</div>
    </div>
    <ag-grid-angular
      style="width: 100%;margin-bottom:16px;"
      [ngStyle]="style"
      class="ag-theme-balham grid-minHeight"
      [rowData]="_rowData"
      [rowHeight]="32"
      [modules]="modules"
      [enableColResize]="true"
      [suppressLoadingOverlay]="true"
      [suppressNoRowsOverlay]="true"
      [suppressContextMenu]="true"
      [suppressDragLeaveHidesColumns]="true"
      [suppressMovableColumns]="true"
      [columnDefs]="columnDefs"
      [suppressRowClickSelection]="suppressRowClickSelection"
      [rowSelection]="rowSelection"
      [toolPanelSuppressSideButtons]="true"
      [localeText]="localeText"
      [enableCellTextSelection]="true"
      [rowDragManaged]="rowDragManaged"
      [singleClickEdit]="true"
      [frameworkComponents]="frameworkComponents"
      [stopEditingWhenGridLosesFocus]="false"
      [enterMovesDownAfterEdit]="true"
      [enterMovesDown]="false"
      (cellClicked)="onCellClicked($event)"
      (cellEditingStarted)="onCellEditingStarted()"
      (cellEditingStopped)="onCellEditingStopped($event)"
      (cellValueChanged)="onCellValueChanged($event)"
      (cellMouseOver)="onCellMouseOver($event)"
      (cellMouseOut)="onCellMouseOut($event)"
      (cellMouseDown)="onCellMouseDown($event)"
      (selectionChanged)="onSelectionChanged($event)"
      (rowDataChanged)="onRowDataChanged($event)"
      (rowDataUpdated)="onRowDataChanged($event)"
      (rowDragEnd)="onSortChanged($event)"
      (bodyScroll)="onScroll($event)"
      [rowClassRules]="rowClassRules"
      [context]="context"
      (gridReady)="onGridReady($event)"
      [defaultColDef]="defaultColDef"
      [floatingFilter]="floatingFilter"
      (firstDataRendered)="onFirstDataRendered($event)"
      [domLayout]="domLayout"
      [class.ag-theme-height]="domLayout !== 'autoHeight'"
      [class.ag-theme-autoHeight]="domLayout == 'autoHeight'"
      [masterDetail]="isDetail"
      [animateRows]="isDetail"
      [isRowMaster]="isRowMaster"
      [detailRowHeight]="detailRowHeight"
      [detailCellRenderer]="detailCellRenderer"
      [detailCellRendererParams]="detailCellRendererParams"
      [autoGroupColumnDef]="autoGroupColumnDef"
      [pinnedBottomRowData]="pinnedBottomRowData">
    </ag-grid-angular>
    <div *ngIf="showTotal" style="text-align: right;">总行数{{_rowData.length}}</div>
  `,
  host: {},
  styles: [`
    .grid-minHeight {
      min-height: 300px;
    }

    .grid-button {
      color: #0589dd;
    }

    .grid-button:hover, .grid-button:focus {
      color: #66c1fc;
      border-color: #66c1fc;
    }

    .grid-button.disabled, .grid-button.disabled:hover, .grid-button.disabled:focus, .grid-button.disabled:active, .grid-button.disabled.active, .grid-button[disabled], .grid-button[disabled]:hover, .grid-button[disabled]:focus, .grid-button[disabled]:active, .grid-button[disabled].active {
      color: #999;
      background-color: #fff;
      border-color: #fff;
    }
  `],
})
//[domLayout]="domLayout"
//[class.ag-theme-height]="domLayout !== 'autoHeight'"
//[class.ag-theme-autoHeight]="domLayout == 'autoHeight'"


export class FormlyFieldGrid extends ApesField {
  public modules: Module[] = AllModules;
  domLayout: any;
  gridApi: any;
  rowSelection: any;
  gridColumnApi: any;
  rowClassRules = {};
  selectData: any;
  localeText: any;
  context = {};
  frameworkComponents;
  columnDefs: any[];
  sortedColumnDefs: any[];
  defaultColDef: any = { width: 100 };
  floatingFilter: boolean = false;
  _rowData: any[] = [];
  tooltipShowDelay;
  sourceNode: any;
  selectAll: boolean = true; // form状态变为submit时是否全选grid项目（默认为全选）
  /*级联*/
  rowCount: number = 0;
  valid = true;
  buttonList = [];
  callback = '';
  checkList = [];
  defaultFilter = [];
  dynamicFilter: boolean = false;
  suppressRowClickSelection: boolean = false;
  btnImportLoading: boolean = false;
  filterData = [];

  rowDragManaged: boolean = false;

  isDetail: boolean = false;
  isRowMaster: any;
  detailCellRenderer: any;
  detailCellRendererParams: any;
  detailList: any;
  detailRowHeight: any = '100';
  detailDomLayout: any;
  detailRowOptions: any;

  pinnedBottomRowData: any[];

  getHide() {
    let expression = this.to.btnhide || 'false';
    return this.expressionService.eval(expression, {
      context: this.formState,
      model: this.formState.model,
    });
  }

  getButtonList() {
    let iLen = this.buttonList.length;
    let expression = 'false';
    for (let i = 0; i < iLen; i++) {
      let button = this.buttonList[i];
      if (button.hasOwnProperty('formId')) {
        expression = 'true';
        break;
      }
    }
    return this.expressionService.eval(expression, {
      context: this.formState,
      model: this.formState.model,
    });
  }

  getImport() {
    let expression = this.to.import || 'false';
    return this.expressionService.eval(expression, {
      context: this.formState,
      model: this.formState.model,
    });
  }

  getButtonHide(id: any) {
    let iLen = this.buttonList.length;
    let expression = 'false';
    for (let i = 0; i < iLen; i++) {
      let button = this.buttonList[i];
      if (id == button.id) {
        expression = button.hide || 'false';
        break;
      }
    }
    return this.expressionService.eval(expression, {
      context: this.formState,
      model: this.formState.model,
    });
  }

  importVisible: boolean = false;
  importData: any;
  noImport = true;
  data: any;
  fileList: UploadFile[] = [];
  sort = true;
  style = { height: '300px' };
  btnRemarks: any = '';
  showTotal: boolean = false;
  showSum: boolean = false;
  filtrationSearch: boolean = false;
  filtrationText: any;
  autoGroupColumnDef: any = null;


  constructor(
    protected gridConfigService: GridConfigService,
    protected events: Events,
    protected expressionService: ExpressionService,
    private modalService: ApesModalService,
    protected apiService: ApiService,
    protected subject: SubjectService,
    private xlsx: XlsxService,
    private renderer: Renderer2,
    protected searchService: SearchService,
    protected msg: ApesMessageService,
    private areaService: AreaService,
    private zone: NgZone,
    private router: Router,
    private formService: FormService,
  ) {
    super(apiService, events, expressionService, subject);
    this.localeText = gridConfigService.getLocaleText();
    this.tooltipShowDelay = 0;
    this.frameworkComponents = {
      input: EditorInputComponent,
      inputNumber: EditorInputNumberComponent,
      inputGroup: EditorInputGroupComponent,
      dialog: RenderDialogComponent,
      textarea: EditorTextAreaComponent,
      select: EditorSelectComponent,
      chartSelect: EditorChartSelectComponent,
      date: EditorDateComponent,
      dateMonth: EditorDateMonthComponent,
      comboGrid: EditorCombogridComponent,
      uomSelect: EditorUomSelectComponent,
      checkBox: EditorCheckBoxComponent,
      // button: RenderButtonComponent,  用于弹框grid
      timeRange: EditorTimeRangeComponent,
      time: EditorTimeComponent,
      renderTimeRange: ApesRenderTimeRangeComponent,
      renderTime: ApesRenderTimeComponent,
      renderSelect: ApesRenderSelectComponent,
      imgPreview: RenderImageReviewComponent,
      dialogButton: RenderOperatingButtonComponent,
      switch: RenderSwitchComponent,
      details: EditorDetailsComponent,
      sort: RenderSortComponent,
      upload: RenderUploadComponent,
      customTooltip: CustomTooltip,
      cityPicker: EditorCityPickerComponent,
      renderCityPicker: ApesRenderCityPicker,
      renderDefault: ApesRenderDefaultComponent,
      tagSelect: EditorTagSelectComponent,
      renderPopover: ApesRenderPopoverComponent,
      renderBadge: ApesRenderBadgeComponent,
      renderTooltip: RenderTooltipComponent,
      customHeader: CustomHeaderComponent,
      showHiddenHeader: ShowHiddenHeaderComponent,
      renderShowHidden: RenderShowHiddenComponent,
      detail: RenderDetailComponent,
      customDetail: RenderCustomDetailComponent,
      xmlDetail: RenderXmlDetailComponent,
      renderTag: RenderTagComponent,
      buttonHeader: ButtonHeaderComponent,
      buttonFilter: ButtonFilterComponent,
    };
    this.domLayout = 'autoHeight';
  }

  ngOnInit() {
    /**初始化表头**/
    this.context['gridName'] = this.key;
    this.context['grid'] = this;
    this.formState['grid_' + this.key] = this;
    this.context = Object.assign(this.context, this.formState);
    this.floatingFilter = this.field['floatingFilter'] ? toBoolean(this.field['floatingFilter']) : this.floatingFilter;
    this.defaultColDef = this.field['filter'] ? {
      ...this.defaultColDef,
      filter: toBoolean(this.field['filter']),
    } : this.defaultColDef;
    this.defaultColDef = this.field['sortable'] ? {
      ...this.defaultColDef,
      filter: toBoolean(this.field['sortable']),
    } : this.defaultColDef;

    this.rowSelection = this.field['rowSelection'] ? this.field['rowSelection'] : 'single';
    this.selectAll = this.field['selectAll'] ? false : true;
    this.domLayout = this.field['domLayout'] ? this.field['domLayout'] : '';
    this.suppressRowClickSelection = this.field['suppressRowClickSelection'] ? toBoolean(this.field['suppressRowClickSelection']) : false;
    this.columnDefs = [];
    this.buttonList = missingOrEmpty(this.field['buttonList']) ? [] : getO(this.field['buttonList']);
    this.callback = missingOrEmpty(this.field['callback']) ? '' : this.field['callback'];
    this.checkList = missingOrEmpty(this.field['checkList']) ? [] : getO(this.field['checkList']);
    this.defaultFilter = missingOrEmpty(this.field['defaultFilter']) ? [] : getO(this.field['defaultFilter']);
    this.dynamicFilter = this.field['dynamicFilter'] ? toBoolean(this.field['dynamicFilter']) : false;
    this.sort = missingOrEmpty(this.field['sort']) ? true : getO(this.field['sort']);
    this.rowClassRules = this.field['rowClassRules'] ? this.field['rowClassRules'] : {};
    this.style = missingOrEmpty(this.field['style']) ? {} : getO(this.field['style']);
    this.btnRemarks = this.field['btnRemarks'] ? this.field['btnRemarks'] : '';
    this.filtrationSearch = this.field['filtrationSearch'] ? this.field['filtrationSearch'] : false;
    this.filtrationText = this.field['filtrationText'] ? this.field['filtrationText'] : '请输入关键字菜单搜索...';
    this.showTotal = !!this.field['showTotal'];
    this.showSum = !!this.field['showSum'];
    this.isDetail = !!this.field['detailType'];
    if (this.isDetail) {
      this.detailCellRenderer = this.field['detailType'];
      this.detailRowHeight = this.field['detailRowHeight'] ? this.field['detailRowHeight'] : '100';
      this.detailRowOptions = this.field['detailRowOptions'] ? getO(this.field['detailRowOptions']) : null;
      if (this.detailCellRenderer == 'detail') {
        this.detailList = this.field['detailList'];
        this.detailDomLayout = this.field['detailDomLayout'] ? this.field['detailDomLayout'] : '';
        this.isRowMaster = (dataItem) => {
          if (this.detailCellRenderer == 'detail') {
            return dataItem ? dataItem[this.detailList].length > 0 : false;
          } else {
            return true;
          }
        };
      }
    }

    if (this.to.columnDefs && this.sort) {
      let colDefOperation = {
        headerName: '序号',
        editable: false,
        field: 'operation',
        pinned: 'left',
        width: 75,
        suppressMenu: true,
        cellRenderer: operationCellRenderer,
      };
      this.columnDefs.push(colDefOperation);
      this.to.columnDefs.forEach(element => {
        let colDef = extend(true, {}, element);
        colDef.editable = false;
        colDef.cellClass = 'cell-color';
        this.columnDefs.push(colDef);
      });
    }
    this.sortedColumnDefs = this.createSortedColumnDefs();

    /**监听表单按钮事件，重新设置表头**/
    this.subject.subscribe(this.formState, this.subject.event_form_button, data => {
      if (data.action && data.action === 'action_new') {
        this.rowCount = 0;
        this.valid = true;
      }
      // if (this.formState.states === 'submit' && this.selectAll) {
      //   // 筛选和selectAll无法共存
      //   if(this.filterSign){
      //     this.gridApi.selectAllFiltered();
      //   } else {
      //     this.gridApi.selectAll();
      //   }
      // }
      this.addListener(this.subject.event_form_button, data);
      this.setColumns();
      //setTimeout(() => this.selectFilter(), 1000);
    });


    /**监听表单刷新事件，初始化表格数据**/
    this.subject.subscribe(this.formState, this.subject.event_form_refresh, data => {
      this._rowData = [];
      this.addListener(this.subject.event_form_refresh, data);
      this.getRowData();
      //setTimeout(() => this.selectFilter(), 1000);
    });
    let tableName = this.key;

    /*** 重新设置表头**/
    this.subject.subscribe(this.formState, this.subject.event_grid_rest_columns + tableName, data => {
      if (data) {
        this._rowData = data;
      }
      this.setColumns();
    });
    /**监听事件，动态添加表格数据**/
    this.subject.subscribe(this.formState, this.subject.event_grid_fill + tableName, data => {
      if (this.defaultFilter.length > 0 && data instanceof Array) {
        let condition = this.defaultFilter[0];
        let dealData = data.filter(item => item[condition.field] == condition.value);
        this.filterData = data.filter(item => item[condition.field] != condition.value);
        this.addRowData(dealData);
      } else {
        this.addRowData(data);
      }

      this.gridApi.selectAll();
      if (this.rowSelection == 'single') {
        this.patchValue();
      }
      // setTimeout(() => this.selectFilter(), 2000);
    });

    /**监听事件，动态过滤显示表格数据**/
    this.subject.subscribe(this.formState, this.subject.event_grid_filter + tableName, data => {

      this._rowData = [];
      let condition = this.defaultFilter[0];
      let dealData = data.filter(item => item[condition.field] == condition.value);
      this.filterData = data.filter(item => item[condition.field] != condition.value);
      this.gridApi.setRowData(dealData);
      this._rowData = dealData;
    });

    /**监听事件，动态修改表格数据**/
    this.subject.subscribe(this.formState, this.subject.event_grid_update + tableName, data => {
      // console.log('修改表格数据', data);
      this.gridApi.applyTransaction({ update: data });

      // 用于动态刷新rowIndex和selelcted状态
      // const rows = this.getRows();
      // rows.forEach(item => this.deleteRow(item));
      // this.gridApi.applyTransaction({ add: rows });
      // if (this.rowSelection === 'multiple') {
      //   this.gridApi.forEachNode((node) => {
      //     if (node.data.hasOwnProperty('selected')) {
      //       let selected = node.data['selected'];
      //       node.setSelected(selected);
      //     }
      //   });
      // }

      this.patchValue();
      //this.selectFilter();

    });

    /**监听字段变更事件，数据回填**/

    this.subject.subscribe(this.formState, tableName, data => {
      if (missing(data.params)) {
        this.valid = true;
        return;
      }
      this.sortedColumnDefs.forEach(element => {
        if (missing(data.params.colDef)) return;
        /**字段回填：onDepends配置回填**/
        this.processOnDepends(element, data.params);
        /**字段回填：context配置回填**/
        this.processContext(element, data.params);
      });

      // 用于注入排序字段
      const rows = this.getRows();
      let sort = 0;
      rows.forEach(row => {
        if (row) {
          row['sort'] = sort;
          sort += 1;
        }
      });

    });
    /*监听关联表格点击事件*/
    this.subject.subscribe(this.formState, this.subject.event_grid_cascade + this.to.source + '_' + tableName, node => {
      this.sourceNode = node;
      this._rowData = node.data[tableName] || [];
    });

    /**监听表单刷新事件，初始化表格数据**/
    this.subject.subscribe(this.formState, this.subject.event_grid_cell_stop_editor, data => {
      if (this.formState.hasOwnProperty('gridCellEditorStopped') && !this.formState.gridCellEditorStopped) {
        this.gridApi.stopEditing();
        this.formState.gridCellEditorStopped = true;
      }
    });

    /***
     * 监听表格行改变事件(取最后一次)
     */
    this.subject.getSubject(this.formState, this.subject.event_from_grid_update + '_' + tableName).pipe(
      debounceTime(500),
    ).subscribe(data => {
      this.subject.publish(this.formState, this.subject.event_from_grid_stop_update + '_' + tableName, this.getRows());
    });

    if (this.filtrationSearch) {
      this.searchSubject.pipe().subscribe((data) => {
        if (data) {
          this.gridApi.expandAll();
        } else {
          this.gridApi.collapseAll();
        }
        this.gridApi.setQuickFilter(data);
      });
    }

  }


  /**
   * 功能：注册事件监听器
   * @param {string} topic
   * @param value
   */
  private addListener(topic: string, value: any) {
    this.to.columnDefs.forEach(element => {
      let events = element.templateOptions.events;
      if (missing(events)) return;
      events.forEach(em => {
        em.type.split(',').filter(type => type === topic)
          .forEach(type => {
            this.expressionService.evaluate(em.callback, {
              context: this.formState,
              form: this.form,
              model: this.formState.model,
              value: value,
            }, true);
          });
      });
    });
  }

  /**
   * 功能：字段回填（context配置回填）
   * @param element 字段元数据
   * @param params
   */
  private processContext(element: any, params: any) {
    /**字段回填：context配置回填**/
    let source = params.colDef.field;
    if (element.field !== source) return;
    let context = element.context || undefined;
    if (missing(context)) return;
    context = getO(context);
    for (let key in context) {
      /**防止死循环，不能自己变更自己**/
      if (key === source) continue;
      let text = getText(context[key]);
      const callValue = missing(text) ? context[key] : getValueUsingField(params.data, text, true);
      params.node.setDataValue(key, exists(callValue) ? callValue : '');
    }
  }

  /**
   * 功能：字段回填（onDepends配置回填）
   * @param element 字段元数据
   * @param params
   */
  private processOnDepends(element: any, params: any) {
    /**字段回填：onDepends配置回填**/
    let source = params.colDef.field;
    /**防止死循环，不能自己变更自己**/
      // if (element.field === source) return;
    let metadata = element.onDepends;
    this.processOnDepend(element, params, metadata, source);
  }

  private processOnDepend(element: any, params: any, metadata: any, source: any) {
    if (missing(metadata)) return;
    let t = type(metadata);
    if (t === 'string') {
      metadata = JSON.parse(metadata);
    }
    t = type(metadata);
    if (t === 'array') {
      metadata.forEach(m => this.processOnDepend(element, params, m, source));
    } else if (t === 'object') {
      for (let field of metadata.fields) {
        if (field !== source) continue;
        let expression = metadata.method;
        let result = this.expressionService.evaluate(expression, {
          context: params.context,
          form: this.form,
          model: params.context.model,
          field: this,
          node: params.node,
          data: params.data,
          value: params.value,
          oldValue: params.oldValue,
          source: source,
        }, true);
        if (expression.indexOf('return') >= 0 && result != undefined) {
          params.node.setDataValue(element.field, result);
        }
        break;
      }
    }
  }

  ngOnDestroy() {
  }

  /**
   * 功能：初始化表格数据
   * @returns {any}
   */
  private getRowData() {
    /**编辑状态**/
    if (this.formState.states === 'submit') {
      return;
    }
    let rowData = this.formState.model[this.key] || this.formControl.value || [];
    if (this.defaultFilter.length > 0) {
      let condition = this.defaultFilter[0];
      let dealData = rowData.filter(item => item[condition.field] == condition.value);
      this.filterData = rowData.filter(item => item[condition.field] != condition.value);
      this._rowData = dealData;
    } else {
      this._rowData = rowData;
    }
    if (this.showSum) {
      const sumFieldObj = this.getSumField();
      if (sumFieldObj.sumFieldList.length > 0) {
        this.setPinnedBottomRowData(sumFieldObj.fieldObj, sumFieldObj.sumFieldList, this._rowData, this._rowData.length);
      }
    }
  }

  /**
   * 功能：重新设置表头
   * @param ctx
   */
  private setColumns() {
    let bGroup = false;
    if (!this.to.columnDefs) return;
    this.columnDefs = [];
    let detailColumnDefs = [];
    this.valid = false;
    if (this.isDetail) {
      this.detailCellRendererParams = {
        detailRowHeight: this.detailRowHeight,
        detailList: this.detailList,
        detailGridOptions: {
          columnDefs: [],
          domLayout: this.detailDomLayout,
          options: this.detailRowOptions,
        },
        // 原生版才生效，detailCellRenderer 会影响触发
        // getDetailRowData: function(params) {
        //   setTimeout(()=>{
        //     console.log('get--',params);
        //     params.successCallback(params.data);
        //   },5000)
        // },
      };
    }

    if (this.sort) {
      let colDefOperation = {
        headerName: '序号',
        editable: false,
        field: 'operation',
        pinned: 'left',
        suppressMenu: true,
        width: 75,
        cellRenderer: operationCellRenderer,
      };
      this.columnDefs.push(colDefOperation);
    }

    this.to.columnDefs.forEach(element => {
      let colDef = extend(true, {}, element);
      colDef.suppressMenu = true;
      if (element.hasOwnProperty('filter')) {
        colDef.suppressMenu = false;
      }
      if (element.hasOwnProperty('rowDrag')) {
        colDef.rowDrag = true;
        this.rowDragManaged = true;
      }
      if (element.hasOwnProperty('filterComponent')) {
        colDef.filter = element.filterComponent;
        colDef.menuTabs = ['filterMenuTab'];
        colDef.suppressMenu = false;
      }

      let disabled = element.expressionProperties['templateOptions.disabled'] || 'false';
      disabled = this.expressionService.eval(disabled, {
        context: this.formState,
        form: this.form,
        model: this.model,
      });
      colDef.editable = !disabled;

      if (element.hasOwnProperty('changeCellStyle')) {
        // tslint:disable-next-line:no-this-assignment
        let that = this;
        colDef.cellStyle = (params) => {
          let CellStyle = element['changeCellStyle'];
          let res = that.expressionService.eval(CellStyle, params);
          return res;
        };
      }

      if (!colDef.editable) {
        colDef.cellClass = 'cell-disable';
      }
      if (element.hasOwnProperty('tooltipComponent')) {
        // tslint:disable-next-line:no-this-assignment
        let local = this;
        colDef.tooltipValueGetter = (params) => {
          let valueFormatter = element['valueFormatter'];
          let res = local.expressionService.eval(valueFormatter, params);
          return res;
        };
      }

      let required = element.expressionProperties['templateOptions.required'] || 'false';
      required = this.expressionService.eval(required, {
        context: this.formState,
        form: this.form,
        model: this.model,
      });
      if (colDef.editable && required) {
        colDef.cellClass = function(params) {
          return (required && missingOrEmpty(params.value) ? 'cell-required' : 'cell-color');
        };
      }
      let hide = element.hideExpression || 'false';
      colDef.hide = this.expressionService.eval(hide, {
        context: this.formState,
        form: this.form,
        model: this.formState.model,
      });

      let checkboxSelection = element.checkboxSelection || 'false';
      if (checkboxSelection !== 'false') {
        // tslint:disable-next-line:no-this-assignment
        let that = this;
        colDef.checkboxSelection = (params) => {
          let selection = that.expressionService.eval(checkboxSelection, {
            context: that.formState,
            form: that.form,
            model: that.formState.model,
            data: params.data,
          });
          if (selection) {
            params.data['hideSelected'] = false;
          } else {
            params.data['hideSelected'] = true;
          }
          return selection;
        };
      }

      let headerCheckboxSelection = element.headerCheckboxSelection || 'false';
      colDef.headerCheckboxSelection = this.expressionService.eval(headerCheckboxSelection, {
        context: this.formState,
        form: this.form,
        model: this.formState.model,
      });

      // 是否全选非筛选状态的行（默认不全选）
      let headerCheckboxSelectionFilteredOnly = element.headerCheckboxSelectionFilteredOnly || 'false';
      colDef.headerCheckboxSelectionFilteredOnly = this.expressionService.eval(headerCheckboxSelectionFilteredOnly, {
        context: this.formState,
        form: this.form,
        model: this.formState.model,
      }) || false;
      let cellDisabled = element.cellDisabled || 'true';
      colDef.cellDisabled = this.expressionService.eval(cellDisabled, {
        context: this.formState,
        form: this.form,
        model: this.formState.model,
      });
      if (element.hasOwnProperty('sortable')) {
        colDef.sortable = toBoolean(element['sortable']);
        // colDef.sortable = true;
      }
      if (element.buttonList) {
        let buttonList;
        buttonList = replaceAll(element.buttonList, '\'', '"');
        buttonList = replaceAll(buttonList, '`', '\'');
        buttonList = JSON.parse(buttonList);
        buttonList.forEach(btn => {
          let cellButtonListDisabled = btn.disabled || 'false';
          btn.disabled = this.expressionService.eval(cellButtonListDisabled, {
            context: this.formState,
            form: this.form,
            model: this.formState.model,
          });
        });
        colDef.buttonList = buttonList;
      }

      colDef.colId = colDef.field;

      if (element.hasOwnProperty('headerGroup')) {
        element.suppressMovable = true;
        bGroup = true;
      }

      if (element.hasOwnProperty('valueFormatter')) {
        if (element.valueFormatter == 'currency') {
          element.valueFormatter = agCurrency;
        } else if (element.valueFormatter == 'number') {
          element.valueFormatter = agNumber;
          element['valueFormatterMeta'] = 'number';
        }
      }

      if (element.hasOwnProperty('showRowGroup')) {
        this.autoGroupColumnDef = {
          headerName: element.headerName,
          resizable: true,
          width: element.width ? element.width : 150,
          cellRendererParams: {
            innerRenderer: (params) => {
              return params.value;
            },
          },
        };
      }

      // if (element.hasOwnProperty('labelFormatter')) {
      //   let labelFormatter = element.labelFormatter || '';
      //   element.headerName = this.expressionService.eval(labelFormatter, {
      //     context: this.formState,
      //     form: this.form,
      //     model: this.formState.model
      //   });
      // }

      if (this.isDetail && element.hasOwnProperty('customDetail')) {
        detailColumnDefs.push(colDef);
      } else if (!element.hasOwnProperty('showRowGroup')) {
        this.columnDefs.push(colDef);
      }
      this.valid = true;
    });
    if (this.isDetail) {
      this.detailCellRendererParams.detailGridOptions.columnDefs = detailColumnDefs;
    }
    if (this.gridApi) {
      if (bGroup) {
        this.setHeaderGroup();
      }

      this.gridApi.setColumnDefs([]);
      this.gridApi.setColumnDefs(this.columnDefs);
      if (this._rowData) {
        this._rowData = this._rowData.length > 0 ? [...this._rowData] : this.model[this.key] == null ? [] : this.model[this.key];
      }
      // this.gridApi.sizeColumnsToFit();
    }
  }

  private setHeaderGroup() {
    let groupColumnDefs = [];
    this.columnDefs.forEach((item) => {
      let columnDef = item;
      if (item.hasOwnProperty('headerGroup')) {
        if (item.headerGroup == 'false') {
          return;
        }
        columnDef = {};
        columnDef['headerName'] = item.headerGroup;
        let filterColumnDefs = this.columnDefs.filter((v) => v.headerGroup == item.headerGroup);
        columnDef['children'] = filterColumnDefs;
        filterColumnDefs.forEach(item => item.headerGroup = 'false');
      }
      columnDef.suppressMovable = true;
      groupColumnDefs.push(columnDef);
    });
    this.columnDefs = groupColumnDefs;
  }

  onCellEditingStarted() {
    this.formState['gridCellEditorStopped'] = false;
  }

  /**
   * 功能：单元格停止编辑事件
   * @param params
   */
  onCellEditingStopped(params) {
    // console.log('gridEditingStopped--');
    /**向表模型提交数据**/
    this.patchValue();
  }

  /*
  * 选择改变事件
  * */
  onSelectionChanged(params) {
    if (this.rowSelection === 'multiple') {

      this.gridApi.forEachNode((node) => {
        let selected = node.isSelected();
        // 用于处理隐藏checkbox
        if (!node.data) return;
        if (node.data['hideSelected'] == true) {
          node.data['selected'] = false;
        } else {
          node.data['selected'] = selected;
        }

        if (this.callback !== '') {
          this.expressionService.evaluate(this.callback, {
            context: this.formState,
            form: this.form,
            model: this.model,
            data: node.data,
            node: node,
          }, true);
        }
      });

      // 用于解决勾选的时候无法检测明细必填项功能
      setTimeout(() => {
        this.checkRequired(params);
      }, 100);

      this.patchValue();
      let tableName = this.key;
      this.subject.publish(this.formState, tableName, {
        event: 'selectionChanged',
        data: this.gridApi.getSelectedRows(),
      });
    } else if (this.rowSelection === 'single') {
      this.gridApi.forEachNode((node) => {
        let selected = node.isSelected();
        // 用于处理隐藏checkbox
        if (!node.data) return;
        if (node.data['hideSelected'] == true) {
          node.data['selected'] = false;
        } else {
          node.data['selected'] = selected;
        }
      });

      this.patchValue();
      // console.log('select--');
    }
  }


  /**
   * 功能：单元格点击事件
   * @param params
   */
  onCellClicked(param) {
    let tableName = this.key;
    this.to.columnDefs.filter(data => data.master === 'true')
      .forEach(item => {
        /*表名+字段*/
        this.subject.publish(this.formState, this.subject.event_grid_cascade + tableName + '_' + item.field, param);
      });
    this.selectData = param;
  }

  /**
   * 功能：通过数据添加多行
   * @param param
   */
  private addRowData(param) {
    let t = type(param);

    /**编辑状态**/

    if (t == 'array') {
      // 用于直接重新灌行数据，不能直接添加一行，只能全部重新添加行或多行
      const rows = this.getRows();
      if (this.formState.states === 'submit' || (this.formState.states === 'new' && this.dynamicFilter)) {
        rows.forEach(item => this.deleteRow(item));
      }
      this.gridApi.applyTransaction({ add: param });
      this.checkRequired(param);
    } else if (t === 'object') {
      const newItem = {
        add: param['data'],
        addIndex: param['rowIndex'] + 1,
      };
      this.gridApi.applyTransaction(newItem);
      const rows = this.getRows();
      rows.forEach(item => this.deleteRow(item));
      this.gridApi.applyTransaction({ add: rows });
      this.checkRequired(param);
    }
  }

  /**
   * 功能：插入行
   * @param params
   */
  onInsertRow() {
    if (this.checkList.length > 0) {
      let sMsg = '';
      this.checkList.forEach(data => {
          let disabled = 'ctx.model.' + data.field;
          let bcheck = this.expressionService.eval(disabled, {
            context: this.formState,
            form: this.form,
            model: this.model,
          });
          if (!bcheck) {
            sMsg = sMsg + data.name + '必填';
          }
        },
      );
      if (sMsg != '') {
        this.msg.error(sMsg);
        return;
      }
    }
    const newItem = {};

    this.columnDefs.forEach(item => {
      if (item.hasOwnProperty('defaultValue')) {
        let defaultValue = getO(item.defaultValue);

        newItem[item.field] = defaultValue;
      }
    });


    this.addRow(newItem);
  }

  /**
   * 功能：复制行
   * @param params
   */
  onCopyRow(btn) {
    if (this.checkList.length > 0) {
      let sMsg = '';
      this.checkList.forEach(data => {
          let disabled = 'ctx.model.' + data.field;
          let bcheck = this.expressionService.eval(disabled, {
            context: this.formState,
            form: this.form,
            model: this.model,
          });
          if (!bcheck) {
            sMsg = sMsg + data.name + '必填';
          }
        },
      );
      if (sMsg != '') {
        this.msg.error(sMsg);
        return;
      }
    }
    let newItem = {};
    let rowData = {};
    if (btn.hasOwnProperty('mapping')) {
      btn.mapping.forEach(map => {
          rowData[map.target] = this.selectData.data[map.source];
        },
      );
    } else {
      rowData = this.selectData.data;
    }
    if (btn.hasOwnProperty('currentPosition')) {
      let rowIndex = this.selectData.rowIndex + 1;
      newItem = { addIndex: rowIndex, add: [{ ...rowData }] };
    } else {
      newItem = { add: [{ ...rowData }] };
    }
    this.addCurRowData(newItem);
  }

  onDynamicClick(btn, i) {
    if (btn.action == 'copy') {
      this.onCopyRow(btn);
    } else {
      this.onInsertAppointRow(i);
    }
  }

  onInsertAppointRow(index) {
    let formId = '';
    let params = this.buttonList[index];
    let dialog;

    // console.log(this.callback);
    let filterModel = {};
    let model = this.context['model'];
    if (params.hasOwnProperty('filterConditionData')) {
      let filterCondition = JSON.parse(replaceAll(params.filterConditionData, '`', '"'));
      filterCondition.forEach((key) => {
        filterModel[key] = model[key];
      });
    } else {
      filterModel = model;
    }
    if (params['conditionModel'] == true) {
      params = {
        ...params,
        conditionModel: filterModel,
        gridData: this.context['model'][this.key],
      };
    }
    if (params.hasOwnProperty('formId')) {
      formId = params.formId;
    } else {
      formId = params.api;
    }

    if (params.hasOwnProperty('action')) {

      if (params.action == 'link') {
        this.openLinkInsertAppointRow(params);
      } else if (params.action == 'dialog') {

        let multiple = params.rowSelection === 'multiple' || false;

        if (params.hasOwnProperty('custom')) {
          if (params.custom == 'DialogInquiry') {
            dialog = DialogInquiryComponent;
          } else if (params.custom == 'DialogMakeInquiry') {
            dialog = DialogMakeInquiryComponent;
          } else if (params.custom == 'DialogPriceAdvance') {
            dialog = DialogPriceAdvanceComponent;
          }
        }

        if (params.compile) {
          dialog = ApesInputFormComponent;
        }

        const options = {
          multiple: multiple,
          ...params,
        };

        this.searchService.openDialog(formId, options, (result: any) => {

          if (result && (result.length > 0 || typeof result == 'object')) {
            let data = {
              data: result,
              buttonId: params.id,
              multiple: multiple,
            };

            this.expressionService.evaluate(this.callback, {
              context: this.formState,
              form: this.form,
              model: this.model,
              data: data,
              value: result,
            }, true);
          }
        }, dialog).subscribe();
      } else if (params.action == 'confirm') {
        let isShow = false;
        if (params.hasOwnProperty('showConfirm')) {
          isShow = this.expressionService.eval(params['showConfirm'], {
            context: this.formState,
            form: this.form,
            model: this.model,
          });
        }
        if (isShow) {
          let title = params.confirmTitle ? params.confirmTitle : params.name;
          let content = params.confirmContent ? params.confirmContent : params.name;
          let footer = params.confirmBtn;
          footer.map((btn) => {
            btn.onClick = () => {
              if (params.hasOwnProperty('conditionModel')) {
                btn['conditionModel'] = params['conditionModel'];
                btn['gridData'] = params['gridData'];
              }

              if (btn.hasOwnProperty('action')) {
                if (btn.action == 'link') {
                  this.openLinkInsertAppointRow(btn);
                }
              } else {
                this.openDialogInsertAppointRow(btn, btn.formId);
              }
              this.modalService.closeAll();
            };
          });

          this.modalService.create({
            apesTitle: title,
            apesContent: content,
            apesFooter: footer,
          });
        } else {
          this.openDialogInsertAppointRow(params, formId);
        }
      } else if (params.action == 'button') {

        let callbackBody = params.callback;
        let node = { ...params };

        this.expressionService.evaluate(callbackBody, {
          context: this.context,
          form: this.context['form'],
          model: this.context['model'],
          data: this.data,
          node: node,
        }, true);
      }
    } else {
      this.openDialogInsertAppointRow(params, formId);
    }
  }

  openLinkInsertAppointRow(params) {
    params['currentUrl'] = this.router.url.replace('/', '');
    this.formService.navigateToForm(params);
  }

  openDialogInsertAppointRow(params, formId) {
    let dialog;
    // 用于判断是否新增行或更新表内数据
    if (params.compile) {
      dialog = ApesInputFormComponent;
    }

    this.searchService.openDialog(formId, params, (result: any) => {
      if (result) {

        if (this.checkList.length > 0) {
          let sMsg = '';
          this.checkList.forEach(data => {
              let disabled = 'ctx.model.' + data.field;
              let bcheck = this.expressionService.eval(disabled, {
                context: this.formState,
                form: this.form,
                model: this.model,
              });
              if (!bcheck) {
                sMsg = sMsg + data.name + '必填';
              }
            },
          );
          if (sMsg != '') {
            this.msg.error(sMsg);
            return;
          }
        }


        if (params.compile) {
          let tableName = this.key;
          let rows = [];
          this.gridApi.getSelectedNodes().forEach((node) => {
            let data = node.data;
            for (let key in result) {
              data[key] = result[key];
            }
            rows.push(data);
          });
          this.subject.publish(this.formState, 'event:grid.update' + tableName, rows);

        } else {
          let event = 'onInsertAppointRow';
          this.addRow(result, event);
          this.patchValue();
        }
      }
    }, dialog).subscribe();
  }

  getAllRowDataCount() {
    const data = [];
    if (this.gridApi) {
      this.gridApi.forEachNode(function(node) {
        if (node.data && Object.keys(node.data).length > 0) {
          data.push(node.data);
        }
      });
    }
    return data.length;
  }


  addRow(newItem, event?) {
    this.gridApi.applyTransaction({
      add: [newItem],
    });

    let params = { data: newItem };
    if (this.rowSelection === 'single') {
      this.checkRequired(params);
      let tableName = this.key;
      if (!event) {
        event = 'onInsertRow';
      }
      this.subject.publish(this.formState, tableName, { params: params, event: event });
      this.focusedCell(null, null, null);
    }

  }

  addCurRowData(newItem, event?) {
    this.gridApi.applyTransaction(newItem);

    let params = { data: newItem.add };
    if (this.rowSelection === 'single') {
      this.checkRequired(params);
      let tableName = this.key;
      if (!event) {
        event = 'onInsertRow';
      }
      this.subject.publish(this.formState, tableName, { params: params, event: event });
      this.focusedCell(null, null, null);
    }

  }

  /**
   * 功能：删除行数据
   */
  onRemoveSelected() {
    if (this.selectData) {
      let row = this.selectData.data;
      this.zone.run(() => {
        this.modalService.confirm({
          apesTitle: '<i>是否删除当前在编辑的数据?</i>',
          apesOnOk: () => this.deleteRow(row),
        });
      });
    } else {
      this.msg.error('请选择需要删除行。');
    }
  }

  deleteRow(row) {
    try {
      let result = this.gridApi.applyTransaction({ remove: [row] });
      if (result.remove.length === 0) return;
    } catch (e) {
      return;
    }
    this.patchValue();
    let params = { data: {} };
    this.checkRequired(params);
    let tableName = this.key;
    this.subject.publish(this.formState, tableName, { params: params, event: 'onRemoveSelected' });
  }

  // change(e: Event) {
  //   const node = e.target as HTMLInputElement;
  //   this.xlsx.import(node.files[0]).then(res => this.importData = res);
  //   this.noImport = false;
  // }
  beforeUpload = (file: UploadFile): boolean => {
    let btn = this.getButtonData('import');
    let _limit = btn['limit'] ? toNumber(btn['limit'], null) : null;
    let isRepeat = false;

    this.fileList.map((files) => {
      if (files.name == file.name) {
        isRepeat = true;
      }
    });

    if (isRepeat) {
      this.msg.error('请勿重复上传相同文件');
      return false;
    } else {
      if (_limit !== null) {
        if (this.fileList.length < _limit) {
          this.fileList = this.fileList.concat(file);
        } else {
          this.msg.error('超出上传限制数量');
          return false;
        }
      } else {
        this.fileList = this.fileList.concat(file);
      }
    }

    const item: any = this.fileList[0];
    this.xlsx.import(item).then(res => this.importData = res);
    this.noImport = false;
    return false;
  };

  /*导入*/
  onBtImport() {
    let btn = this.getButtonData('import');
    let importKey = btn['key'] ? btn['key'] : [];

    this.btnImportLoading = true;
    let webTab = [];
    let fieldValue = [];
    if (!this.importData) {
      this.msg.error('请选择导入的文件！');
      this.btnImportLoading = false;
      return;
    }

    // importVisible


    let col = [];

    if (importKey.length !== 0) {
      importKey.forEach((key) => {
        this.columnDefs.forEach((i) => {
          if (key == i.field) {
            col.push(i);
          }
        });
      });
    } else {
      this.columnDefs.forEach((i) => {
        col.push(i);
      });
    }

    col.forEach((i) => {
      let data = {
        widget: i['cellEditor'],
        api: i['cellEditorParams'],
        name: i['headerName'],
        downFormatter: i['downFormatter'],
        field: i['field'],
      };
      webTab.push(data);
    });

    if (this.field.key == 'rewardPunishItems') {
      fieldValue.push(this.form.value);
    }

    let data = {
      data: webTab,
      importData: this.importData,
      fieldkey: this.field.key,
      fieldValue: fieldValue,
      model: this.model,
    };

    if (btn.hasOwnProperty('model')) {
      data['model'] = this.model;
    }

    let length = Object.keys(this.importData).length;
    if (length > 1) {
      this.openImportWorkbookComponent(data);
    } else {
      this.checkImportData(data);
    }
  }


  checkImportData(data) {
    let method = this.field['importApi'] ? this.field['importApi'] : 'api.import';
    let importType = false;
    if (this.field.hasOwnProperty('importType')) {
      importType = true; // 用于控制是否替换或添加数据
    }
    this.apiService.post(method, { 'body': JSON.stringify(data) }).subscribe(dataValue => {
      if (dataValue) {
        this.data = dataValue;
        if (importType) {
          if (this.data.msg !== '') {
            this.msg.error(this.data.msg, { apesDuration: 5000 });
            this.btnImportLoading = false;
            return;
          }
          this._rowData = this.data.items;
        } else {
          let rows = this.xlsx.populateGrid(this.columnDefs, this.data);
          this.addRowData(rows);
        }

        this.patchValue();
        setTimeout(() => {
          this.subject.publish(this.context, 'event:grid.import', this.data);
        }, 500);
      }
      this.btnImportLoading = false;

    });
  }

  getButtonData(id) {
    let iLen = this.buttonList.length;
    let btn = {};
    for (let i = 0; i < iLen; i++) {
      let button = this.buttonList[i];
      if (button.id == id) {
        btn = button;
        break;
      }
    }
    return btn;
  }

  /*导出*/
  onBtExport() {
    // 获取导出exel名称
    let exportBtn = this.buttonList.filter(btn => btn.id === 'export')[0];
    let exportName = exportBtn && exportBtn.name ? exportBtn.name : '导出文件';
    exportName += format(new Date(), 'YYYYMMDDHHmm');


    let btn = this.getButtonData('export');
    let exportKey = btn['key'] ? btn['key'] : [];

    let data = [];
    let col = [];

    if (exportKey.length !== 0) {
      exportKey.forEach((key) => {
        this.columnDefs.forEach((i) => {
          if (key == i.field) {
            col.push(i);
          }
        });
      });
    } else {
      this.columnDefs.forEach((i) => {
        let check = true;
        if (i.hasOwnProperty('exportHide')) {
          let expression = i.exportHide;
          check = !this.expressionService.evaluate(expression, {
            context: this.context,
          });
        }
        if (check) {
          col.push(i);
        }
      });
    }

    data = [col.map(i => i.headerName)];
    this.getRows().forEach(i =>
      data.push(
        col.map(c => {
            let value = deepClone(i[c.field as string]);
            if (value instanceof Object) {
              if (c['exportFormatter']) {
                let expression = c['exportFormatter'];
                value = this.expressionService.evaluate(expression, {
                  value: value,
                  data: i,
                });
              } else {
                value = value.name;
              }
              if (value == undefined) {
                value = i[c.field as string].description;
              }
            } else if (typeof value === 'string' && c.hasOwnProperty('exportFormatter')) {
              let expression = c['exportFormatter'];
              value = this.expressionService.evaluate(expression, {
                value: value,
                data: i,
              });
              if (value == undefined) {
                value = i[c.field as string].description;
              }
            } else if (typeof value === 'boolean' && c.hasOwnProperty('exportFormatter')) {
              let expression = c['exportFormatter'];
              value = this.expressionService.evaluate(expression, {
                value: value,
                data: i,
              });
              if (value == undefined) {
                value = i[c.field as string].description;
              }
            }


            // 处理序号字段为空的问题
            if (c.field === 'operation') value = data.length;

            return value;
          },
        )),
    );

    this.xlsx.export({
      sheets: [
        {
          data: data,
          name: exportName,
        },
      ],
      filename: exportName += '.xlsx',
    });
  }

  /**
   * 功能：获取第一个可编辑列的名称
   * @param params
   */
  private getFirstEditableColumnName(): string {
    for (let element of this.columnDefs) {
      if (element.editable) {
        return element.field;
      }
    }
  }

  /**
   * 功能：聚焦单元格
   */
  private focusedCell(pinned, key, char) {
    let columnName = this.getFirstEditableColumnName();
    let rowIndex = this.gridApi.getDisplayedRowCount() - 1;
    this.gridApi.setFocusedCell(rowIndex, columnName, pinned);
    this.gridApi.startEditingCell({
      rowIndex: rowIndex,
      colKey: columnName,
      rowPinned: pinned,
      keyPress: key,
      charPress: char,
    });
  }

  /**
   * 功能：向表单模型提交变更值
   */
  private patchValue(check = true) {
    if (check) {
      this.formState.gridCellEditorStopped = true;
    }
    const rows = this.getRows();
    let tableName = this.key;
    if (this.to.source !== undefined) {
      if (this.sourceNode !== undefined) {
        this.sourceNode.data[tableName] = rows;
      }
      this.rowCount = rows.length;
    } else {
      if (this.filterData.length > 0) {
        this.filterData.forEach((item) => {
          let check = true;
          rows.forEach((row) => {
            if (row == item) {
              check = false;
            }
          });
          if (check) {
            rows.push(item);
          }
        });
      }
      if (this.dynamicFilter) {
        for (let i = 0; i < rows.length - 1; i++) {
          for (let j = 0; j < rows.length - i - 1; j++) {
            if (rows[j]['sort'] > rows[j + 1]['sort']) {
              let temp = rows[j];
              rows[j] = rows[j + 1];
              rows[j + 1] = temp;
            }
          }
        }
      }
      this.formControl.patchValue(rows);
      this.model[tableName] = rows;
      this.rowCount = rows.length;
    }
  }


  /**
   * 功能：获取表格数据
   * @returns {any[]}
   */
  private getRows(): any[] {
    let rows = [];
    if (this.rowSelection === 'multiple' && this.formState.states === 'submit' && !this.selectAll) {
      //this.gridApi.stopEditing(false);
      this.gridApi.getSelectedNodes().forEach((node) => {
        rows.push(node.data);
      });
    } else {
      if (this.gridApi) {
        this.gridApi.forEachNode((node) => {
          rows.push(node.data);
        });
      } else if (!this.gridApi && this.model[this.key] != null) {
        this.model[this.key].forEach((data) => {
          rows.push(data);
        });
      }
    }
    return rows;
  }

  /**
   * 功能：单元格数据变更事件
   */
  onCellValueChanged(params) {
    // /**非编辑状态**/
    // if (this.formState.states !== 'submit') return;
    /**没有输入任何值**/
    if (missing(params.oldValue) && missing(params.newValue)) return;
    /**数据值没有变更**/
    if (deepCompare(params.oldValue, params.newValue)) return;
    /**检查表格必输项**/
    this.checkRequired(params);
    /**发送单元格数据变更事件**/
    let tableName = this.key;
    this.subject.publish(this.formState, tableName, { params: params, event: 'onCellValueChanged' });
  }

  onRowDataChanged(params) {
    let tableName = this.key;
    this.subject.publish(this.formState, this.subject.event_from_grid_update + '_' + tableName, {});
    this.patchValue(false);
  }

  // 拖拽
  onSortChanged(e) {
    // 用于注入排序字段
    const rows = this.getRows();
    let sort = 0;
    rows.forEach(row => {
      row['sort'] = sort;
      sort += 1;
    });
    this.patchValue();
  }

  onScroll(params) {
    // console.log('-------------scroll-----------------------');
  }

  onCellMouseOver(params) {
    params.node.hovered = true;
    params.event.preventDefault();
    this.gridApi.refreshCells({ force: true, columns: ['operation'] });
    this.editorButton();
  }

  onCellMouseOut(params) {
    // console.log('gridMouseOut--');
    params.node.hovered = false;
    params.event.preventDefault();
    this.gridApi.refreshCells({ force: true, columns: ['operation'] });
  }

  editorButton() {
    let editorBtn = document.querySelector('.ag-editor-button');
    if (editorBtn == null) return;
    let addBtn = editorBtn.children[0];
    if (this.to['disabled'] == false) {
      this.renderer.setStyle(editorBtn, 'display', 'block');
      if (this.valid == true) {
        this.renderer.setStyle(addBtn, 'display', 'inline-block');
      }
    }
  }

  onCellMouseDown(params) {
    if (params.node.hovered == true && this.to['disabled'] != true) {
      if (params.event.target.id == 'add') {
        if (this.valid == true) {
          this.onInsertRow();
        }
      } else if (params.event.target.id == 'del') {
        this.selectData = params;
        this.onRemoveSelected();
      }
    }
  }

  /**
   * 功能：检查表格必输项
   * @param params
   */
  private checkRequired(params) {
    params.valid = true;
    this.valid = true;
    this.formState.valid = true;

    for (let element of this.to.columnDefs) {
      let required = element.expressionProperties['templateOptions.required'] || 'false';
      required = this.expressionService.eval(required, {
        context: this.formState,
        form: this.form,
        model: this.model,
        data: params.data,
      });
      if (required === true) {
        for (let data of this.getRows()) {
          let value = data[element.field];
          if (missing(value)) {
            params.valid = false;
            this.valid = false;
            this.formState.valid = false;
            return;
          }
        }
      }
    }
  }

  private createSortedColumnDefs() {
    /**字段排序**/
    let columns = extend(true, [], this.to.columnDefs);
    columns.sort((x, y) => {
      if (this.contain(x, y)) {
        return -1;
      } else if (this.contain(y, x)) {
        return 1;
      } else {
        return 0;
      }
    });
    return columns;
  }

  private contain(x: any, y: any) {
    let context = x.context;
    if (missing(context) || missing(y)) return false;
    context = getO(context);
    if (type(context) === 'object') {
      for (let key in context) {
        if (key === y.field) return true;
      }
    }
    return false;
  }


  onCellFocuse(params) {
    // console.log(params);
  }

  onBtStopEditing() {
    if (this.formState.hasOwnProperty('gridCellEditorStopped') && !this.formState.gridCellEditorStopped) {
      this.gridApi.stopEditing();
      this.formState.gridCellEditorStopped = true;
    }
  }

  onGridReady(params) {
    this.gridApi = params.api;
    this.gridColumnApi = params.columnApi;
    this.setColumns();
    this.autoSizeAll();
    // 动态渲染,值存在渲染界面
    if (this.formControl.value) {
      this._rowData = this.formControl.value;
    }
  }

  /**
   * 功能：自动列宽
   */
  autoSizeAll() {
    let allColumnIds = [];
    this.gridColumnApi.getAllColumns().forEach(function(column) {
      if (!column.colDef.hasOwnProperty('width')) {
        allColumnIds.push(column.colId);
      }
    });
    this.gridColumnApi.autoSizeColumns(allColumnIds);
  }

  onFirstDataRendered(params) {
    this.autoSizeAll();
  }

  selectFilter(condition) {
    const filterInstance = this.gridApi.getFilterInstance(condition.field);

    filterInstance.setModel({
      type: 'equals',
      filter: condition.value,
    });
    this.gridApi.onFilterChanged();
  }

  private searchSubject = new Subject<string>();
  quickSearchInput: any;

  onFilterTextBoxChanged() {
    let data = this.quickSearchInput;
    this.searchSubject.next(data);
  }

  clearSearch() {
    this.quickSearchInput = '';
    this.onFilterTextBoxChanged();
  }


  openImportWorkbookComponent(data): void {
    let title = '选择需要导入的工作表区域';
    let dialog = null;
    let body = {
      importData: this.importData,
    };
    const openDialog = dialog ? dialog : ApesDialogImportWorkbookComponent;
    const dialogRef = this.modalService.create({
      apesWidth: '25vw',
      apesTitle: title,
      apesContent: openDialog,
      apesComponentParams: body,
      apesMaskClosable: false,
      apesFooter: [
        {
          label: '取消',
          type: 'default',
          onClick: () => {
            this.btnImportLoading = false;
            dialogRef.close();
          },
        },
        {
          label: '确定',
          type: 'primary',
          disabled: (componentInstance) => {
            return !componentInstance['form'].valid;
          },
          onClick: (componentInstance) => {
            // console.log(componentInstance, data);
            data['ImportWorkbook'] = componentInstance['model'].select;
            this.checkImportData(data);
            dialogRef.close();
          },
        },
      ],
    });
  }

  /**
   * 功能：获取需要合计的字段
   * sumFieldList 合计字段数组，用来存放需要合计的字段
   * fieldObj 一行数据的对象，用于合计展示
   * sumFieldData 发送给后端合计数据的精度
   * sumFieldStr 合计字段
   * @returns {{sumFieldList: any[]; fieldObj: {}; sumOption: {}; sumFieldStr: string}}
   */
  getSumField() {
    const sumFieldList = [];
    const fieldObj = {};
    let sumOption = {};
    let sumFieldStr = '';
    // const columnList = this.gridOptions.columnDefs;
    const columnList = this.columnDefs;
    for (let i = 0, lent = columnList.length; i < lent; i++) {
      const columnObj = columnList[i];
      fieldObj[columnObj['field']] = '';

      if (columnObj['sum'] && toBoolean(columnObj['sum'])) {
        sumFieldList.push(columnObj['field']);
        sumFieldStr += `${columnObj['field']};`;
        sumOption[columnObj['field']] = { scale: columnObj['scale'] ? columnObj['scale'] : 2 };
      }
    }
    return { sumFieldList: sumFieldList, fieldObj: fieldObj, sumOption: sumOption, sumFieldStr: sumFieldStr };
  }

  /**
   * 功能：计算出合计的字段
   * @param fieldObj
   * @param sumFieldList
   * @param sumResultList
   */
  setPinnedBottomRowData(fieldObj, sumFieldList, sumResultList, bRow) {
    if (bRow > 0) {
      for (let i = 0, len = sumFieldList.length; i < len; i++) {
        const fieldKey = sumFieldList[i];
        // fieldObj[fieldKey] = sumResultList[0][fieldKey];
        let sum = 0;
        sumResultList.forEach((list) => {
          if (list[fieldKey]) {
            sum += toNumber(list[fieldKey]);
          }
        });
        fieldObj[fieldKey] = sum;
      }
    } else {
      fieldObj = [];
    }
    fieldObj['hideBtnBar'] = 'true';

    this.pinnedBottomRowData = [fieldObj];
  }
}

@Component({
  selector: 'apes-dialog-importWorkbook-component',
  template: `
    <div apes-row>
      <formly-form [model]="model" [fields]="field" [options]="options" [form]="form">
      </formly-form>
    </div>
  `,
  styles: [``],
  encapsulation: ViewEncapsulation.None,
})
export class ApesDialogImportWorkbookComponent implements OnInit {
  params: any;
  resultData: any;
  form = new FormGroup({});
  model: any = {};
  options: FormlyFormOptions = {};

  field: FormlyFieldConfig[] = [
    {
      key: 'select',
      type: 'select',
      templateOptions: {
        label: '工作表',
        items: [],
        required: true,
        downFormatter: 'value',
        valueFormatter: 'value',
        divCol: 24,
      },
    }];

  constructor(
    private modal: ApesModalRef,
  ) {
  }

  ngOnInit() {
    this.params = deepClone(this.modal['apesComponentParams']);
    let items = [];
    for (let key in this.params.importData) {
      items.push(key);
    }

    this.field[0].templateOptions.items = JSON.stringify(items);
  }

  destroyModal(): void {
    this.modal.destroy(this.resultData);
  }

}

